home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Environments
/
PowerLisp 2.01
/
Supplemental Documentation
/
Documentation
/
Chapter 11. Packages
< prev
next >
Wrap
Text File
|
1995-03-27
|
97KB
|
2,058 lines
Common Lisp the Language, 2nd Edition
-------------------------------------------------------------------------------
11. Packages
One problem with earlier Lisp systems is the use of a single name space for all
symbols. In large Lisp systems, with modules written by many different
programmers, accidental name collisions become a serious problem. Common Lisp
addresses this problem through the package system, derived from an earlier
package system developed for Lisp Machine Lisp [55]. In addition to preventing
name-space conflicts, the package system makes the modular structure of large
Lisp systems more explicit.
A package is a data structure that establishes a mapping from print names
(strings) to symbols. The package thus replaces the ``oblist'' or ``obarray''
machinery of earlier Lisp systems. At any given time one package is current,
and this package is used by the Lisp reader in translating strings into
symbols. The current package is, by definition, the one that is the value of
the global variable *package*. It is possible to refer to symbols in packages
other than the current one through the use of package qualifiers in the printed
representation of the symbol. For example, foo:bar, when seen by the reader,
refers to the symbol whose name is bar in the package whose name is foo.
(Actually, this is true only if bar is an external symbol of foo, that is, a
symbol that is supposed to be visible outside of foo. A reference to an
internal symbol requires the intentionally clumsier syntax foo::bar.)
The string-to-symbol mappings available in a given package are divided into two
classes, external and internal. We refer to the symbols accessible via these
mappings as being external and internal symbols of the package in question,
though really it is the mappings that are different and not the symbols
themselves. Within a given package, a name refers to one symbol or to none; if
it does refer to a symbol, then it is either external or internal in that
package, but not both.
External symbols are part of the package's public interface to other packages.
External symbols are supposed to be chosen with some care and are advertised to
users of the package. Internal symbols are for internal use only, and these
symbols are normally hidden from other packages. Most symbols are created as
internal symbols; they become external only if they appear explicitly in an
export command for the package.
A symbol may appear in many packages. It will always have the same name
wherever it appears, but it may be external in some packages and internal in
others. On the other hand, the same name (string) may refer to different
symbols in different packages.
Normally, a symbol that appears in one or more packages will be owned by one
particular package, called the home package of the symbol; that package is said
to own the symbol. Every symbol has a component called the package cell that
contains a pointer to its home package. A symbol that is owned by some package
is said to be interned. Some symbols are not owned by any package; such a
symbol is said to be uninterned, and its package cell contains nil.
Packages may be built up in layers. From the point of view of a package's user,
the package is a single collection of mappings from strings into internal and
external symbols. However, some of these mappings may be established within the
package itself, while other mappings are inherited from other packages via the
use-package construct. (The mechanisms responsible for this inheritance are
described below.) In what follows, we will refer to a symbol as being
accessible in a package if it can be referred to without a package qualifier
when that package is current, regardless of whether the mapping occurs within
that package or via inheritance. We will refer to a symbol as being present in
a package if the mapping is in the package itself and is not inherited from
somewhere else. Thus a symbol present in a package is accessible, but an
accessible symbol is not necessarily present.
A symbol is said to be interned in a package if it is accessible in that
package and also is owned (by either that package or some other package).
Normally all the symbols accessible in a package will in fact be owned by some
package, but the terminology is useful when discussing the pathological case of
an accessible but unowned (uninterned) symbol.
As a verb, to intern a symbol in a package means to cause the symbol to be
interned in the package if it was not already; this process is performed by the
function intern. If the symbol was previously unowned, then the package it is
being interned in becomes its owner (home package); but if the symbol was
previously owned by another package, that other package continues to own the
symbol.
To unintern a symbol from the package means to cause it to be not present in
the package and, additionally, to cause the symbol to be uninterned if the
package was the home package (owner) of the symbol. This process is performed
by the function unintern.
-------------------------------------------------------------------------------
* Consistency Rules
* Package Names
* Translating Strings to Symbols
* Exporting and Importing Symbols
* Name Conflicts
* Built-in Packages
* Package System Functions and Variables
* Modules
* An Example
-------------------------------------------------------------------------------
11.1. Consistency Rules
Package-related bugs can be very subtle and confusing: things are not what they
appear to be. The Common Lisp package system is designed with a number of
safety features to prevent most of the common bugs that would otherwise occur
in normal use. This may seem over-protective, but experience with earlier
package systems has shown that such safety features are needed.
In dealing with the package system, it is useful to keep in mind the following
consistency rules, which remain in force as long as the value of *package* is
not changed by the user:
* Read-read consistency: Reading the same print name always results in the
same (eq) symbol.
* Print-read consistency: An interned symbol always prints as a sequence of
characters that, when read back in, yields the same (eq) symbol.
* Print-print consistency: If two interned symbols are not eq, then their
printed representations will be different sequences of characters.
These consistency rules remain true in spite of any amount of implicit
interning caused by typing in Lisp forms, loading files, etc. This has the
important implication that, as long as the current package is not changed,
results are reproducible regardless of the order of loading files or the exact
history of what symbols were typed in when. The rules can only be violated by
explicit action: changing the value of *package*, forcing some action by
continuing from an error, or calling one of the ``dangerous'' functions
unintern, unexport, shadow, shadowing-import, or unuse-package.
-------------------------------------------------------------------------------
11.2. Package Names
Each package has a name (a string) and perhaps some nicknames. These are
assigned when the package is created, though they can be changed later. A
package's name should be something long and self-explanatory, like editor;
there might be a nickname that is shorter and easier to type, such as ed.
There is a single name space for packages. The function find-package translates
a package name or nickname into the associated package. The function
package-name returns the name of a package. The function package-nicknames
returns a list of all nicknames for a package. The function rename-package
removes a package's current name and nicknames and replaces them with new ones
specified by the user. Package renaming is occasionally useful when, for
development purposes, it is desirable to load two versions of a package into
the same Lisp. One can load the first version, rename it, and then load the
other version, without getting a lot of name conflicts.
When the Lisp reader sees a qualified symbol, it handles the package-name part
in the same way as the symbol part with respect to capitalization. Lowercase
characters in the package name are converted to corresponding uppercase
characters unless preceded by the escape character or surrounded by |
characters. The lookup done by the find-package function is case-sensitive,
like that done for symbols. Note that |Foo|:|Bar| refers to a symbol whose name
is Bar in a package whose name is Foo. By contrast, |Foo:Bar| refers to a
seven-character symbol that has a colon in its name (as well as two uppercase
letters and four lowercase letters) and is interned in the current package.
Following the convention used in this book for symbols, we show ordinary
package names using lowercase letters, even though the name string is
internally represented with uppercase letters.
Most of the functions that require a package-name argument from the user accept
either a symbol or a string. If a symbol is supplied, its print name will be
used; the print name will already have undergone case-conversion by the usual
rules. If a string is supplied, it must be so capitalized as to match exactly
the string that names the package.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
one may use either a package object or a package name (symbol or string) in any
of the following situations:
* the :use argument to make-package
* the first argument to package-use-list, package-used-by-list,
package-name, package-nicknames, in-package, find-package, rename-package,
or delete-package,
* the second argument to intern, find-symbol, unintern, export, unexport,
import, shadowing-import, or shadow
* the first argument, or a member of the list that is the first argument,
to use-package or unuse-package
* the value of the package given to do-symbols, do-external-symbols, or
do-all-symbols
* a member of the package-list given to with-package-iterator
Note that the first argument to make-package must still be a package name and
not an actual package; it makes no sense to create an already existing package.
Similarly, package nicknames must always be expressed as package names and not
as package objects. If find-package is given a package object instead of a
name, it simply returns that package.
[change_end]
-------------------------------------------------------------------------------
11.3. Translating Strings to Symbols
The value of the special variable *package* must always be a package object
(not a name). Whatever package object is currently the value of *package* is
referred to as the current package.
When the Lisp reader has, by parsing, obtained a string of characters thought
to name a symbol, that name is looked up in the current package. This lookup
may involve looking in other packages whose external symbols are inherited by
the current package. If the name is found, the corresponding symbol is
returned. If the name is not found (that is, there is no symbol of that name
accessible in the current package), a new symbol is created for it and is
placed in the current package as an internal symbol. Moreover, the current
package becomes the owner (home package) of the symbol, and so the symbol
becomes interned in the current package. If the name is later read again while
this same package is current, the same symbol will then be found and returned.
Often it is desirable to refer to an external symbol in some package other than
the current one. This is done through the use of a qualified name, consisting
of a package name, then a colon, then the name of the symbol. This causes the
symbol's name to be looked up in the specified package, rather than in the
current one. For example, editor:buffer refers to the external symbol named
buffer accessible in the package named editor, regardless of whether there is a
symbol named buffer in the current package. If there is no package named
editor, or if no symbol named buffer is accessible in editor, or if buffer is
an internal symbol in editor, the Lisp reader will signal a correctable error
to ask the user for instructions.
On rare occasions, a user may need to refer to an internal symbol of some
package other than the current one. It is illegal to do this with the colon
qualifier, since accessing an internal symbol of some other package is usually
a mistake. However, this operation is legal if a doubled colon :: is used as
the separator in place of the usual single colon. If editor::buffer is seen,
the effect is exactly the same as reading buffer with *package* temporarily
rebound to the package whose name is editor. This special-purpose qualifier
should be used with caution.
The package named keyword contains all keyword symbols used by the Lisp system
itself and by user-written code. Such symbols must be easily accessible from
any package, and name conflicts are not an issue because these symbols are used
only as labels and never to carry package-specific values or properties.
Because keyword symbols are used so frequently, Common Lisp provides a special
reader syntax for them. Any symbol preceded by a colon but no package name (for
example :foo) is added to (or looked up in) the keyword package as an external
symbol. The keyword package is also treated specially in that whenever a symbol
is added to the keyword package the symbol is always made external; the symbol
is also automatically declared to be a constant (see defconstant) and made to
have itself as its value. This is why every keyword evaluates to itself. As a
matter of style, keywords should always be accessed using the leading-colon
convention; the user should never import or inherit keywords into any other
package. It is an error to try to apply use-package to the keyword package.
Each symbol contains a package cell that is used to record the home package of
the symbol, or nil if the symbol is uninterned. This cell may be accessed by
using the function symbol-package. When an interned symbol is printed, if it is
a symbol in the keyword package, then it is printed with a preceding colon;
otherwise, if it is accessible (directly or by inheritance) in the current
package, it is printed without any qualification; otherwise, it is printed with
the name of the home package as the qualifier, using : as the separator if the
symbol is external and :: if not.
A symbol whose package slot contains nil (that is, has no home package) is
printed preceded by #:. It is possible, by the use of import and unintern, to
create a symbol that has no recorded home package but that in fact is
accessible in some package. The system does not check for this pathological
case, and such symbols will always be printed preceded by #:.
In summary, the following four uses of symbol qualifier syntax are defined.
foo:bar
When read, looks up BAR among the external symbols of the package named
FOO. Printed when symbol bar is external in its home package foo and is
not accessible in the current package.
foo::bar
When read, interns BAR as if FOO were the current package. Printed when
symbol bar is internal in its home package foo and is not accessible in
the current package.
:bar
When read, interns BAR as an external symbol in the keyword package and
makes it evaluate to itself. Printed when the home package of symbol bar
is keyword.
#:bar
When read, creates a new uninterned symbol named BAR. Printed when the
symbol bar is uninterned (has no home package), even in the pathological
case that bar is uninterned but nevertheless somehow accessible in the
current package.
All other uses of colons within names of symbols are not defined by Common Lisp
but are reserved for implementation-dependent use; this includes names that end
in a colon, contain two or more colons, or consist of just a colon.
-------------------------------------------------------------------------------
11.4. Exporting and Importing Symbols
Symbols from one package may be made accessible in another package in two ways.
First, any individual symbol may be added to a package by use of the function
import. The form (import 'editor:buffer) takes the external symbol named buffer
in the editor package (this symbol was located when the form was read by the
Lisp reader) and adds it to the current package as an internal symbol. The
symbol is then present in the current package. The imported symbol is not
automatically exported from the current package, but if it is already present
and external, then the fact that it is external is not changed. After the call
to import it is possible to refer to buffer in the importing package without
any qualifier. The status of buffer in the package named editor is unchanged,
and editor remains the home package for this symbol. Once imported, a symbol is
present in the importing package and can be removed only by calling unintern.
If the symbol is already present in the importing package, import has no
effect. If a distinct symbol with the name buffer is accessible in the
importing package (directly or by inheritance), then a correctable error is
signaled, as described in section 11.5, because import avoids letting one
symbol shadow another.
A symbol is said to be shadowed by another symbol in some package if the first
symbol would be accessible by inheritance if not for the presence of the second
symbol. To import a symbol without the possibility of getting an error because
of shadowing, use the function shadowing-import. This inserts the symbol into
the specified package as an internal symbol, regardless of whether another
symbol of the same name will be shadowed by this action. If a different symbol
of the same name is already present in the package, that symbol will first be
uninterned from the package (see unintern). The new symbol is added to the
package's shadowing-symbols list. shadowing-import should be used with caution.
It changes the state of the package system in such a way that the consistency
rules do not hold across the change.
The second mechanism is provided by the function use-package. This causes a
package to inherit all of the external symbols of some other package. These
symbols become accessible as internal symbols of the using package. That is,
they can be referred to without a qualifier while this package is current, but
they are not passed along to any other package that uses this package. Note
that use-package, unlike import, does not cause any new symbols to be present
in the current package but only makes them accessible by inheritance.
use-package checks carefully for name conflicts between the newly imported
symbols and those already accessible in the importing package. This is
described in detail in section 11.5.
Typically a user, working by default in the user package, will load a number of
packages into Lisp to provide an augmented working environment, and then call
use-package on each of these packages to allow easy access to their external
symbols. unuse-package undoes the effects of a previous use-package. The
external symbols of the used package are no longer inherited. However, any
symbols that have been imported into the using package continue to be present
in that package.
There is no way to inherit the internal symbols of another package; to refer to
an internal symbol, the user must either make that symbol's home package
current, use a qualifier, or import that symbol into the current package.
[change_begin]
The distinction between external and internal symbols is a primary means of
hiding names so that one program does not tread on the namespace of another.
[change_end]
When intern or some other function wants to look up a symbol in a given
package, it first looks for the symbol among the external and internal symbols
of the package itself; then it looks through the external symbols of the used
packages in some unspecified order. The order does not matter; according to the
rules for handling name conflicts (see below), if conflicting symbols appear in
two or more packages inherited by package X, a symbol of this name must also
appear in X itself as a shadowing symbol. Of course, implementations are free
to choose other, more efficient ways of implementing this search, as long as
the user-visible behavior is equivalent to what is described here.
The function export takes a symbol that is accessible in some specified package
(directly or by inheritance) and makes it an external symbol of that package.
If the symbol is already accessible as an external symbol in the package,
export has no effect. If the symbol is directly present in the package as an
internal symbol, it is simply changed to external status. If it is accessible
as an internal symbol via use-package, the symbol is first imported into the
package, then exported. (The symbol is then present in the specified package
whether or not the package continues to use the package through which the
symbol was originally inherited.) If the symbol is not accessible at all in the
specified package, a correctable error is signaled that, upon continuing, asks
the user whether the symbol should be imported.
The function unexport is provided mainly as a way to undo erroneous calls to
export. It works only on symbols directly present in the current package,
switching them back to internal status. If unexport is given a symbol already
accessible as an internal symbol in the current package, it does nothing; if it
is given a symbol not accessible in the package at all, it signals an error.
-------------------------------------------------------------------------------
11.5. Name Conflicts
A fundamental invariant of the package system is that within one package any
particular name can refer to at most one symbol. A name conflict is said to
occur when there is more than one candidate symbol and it is not obvious which
one to choose. If the system does not always choose the same way, the read-read
consistency rule would be violated. For example, some programs or data might
have been read in under a certain mapping of the name to a symbol. If the
mapping changes to a different symbol, and subsequently additional programs or
data are read, then the two programs will not access the same symbol even
though they use the same name. Even if the system did always choose the same
way, a name conflict is likely to result in a mapping from names to symbols
different from what was expected by the user, causing programs to execute
incorrectly. Therefore, any time a name conflict is about to occur, an error is
signaled. The user may continue from the error and tell the package system how
to resolve the conflict.
It may be that the same symbol is accessible to a package through more than one
path. For example, the symbol might be an external symbol of more than one used
package, or the symbol might be directly present in a package and also
inherited from another package. In such cases there is no name conflict. The
same identical symbol cannot conflict with itself. Name conflicts occur only
between distinct symbols with the same name.
The creator of a package can tell the system in advance how to resolve a name
conflict through the use of shadowing. Every package has a list of shadowing
symbols. A shadowing symbol takes precedence over any other symbol of the same
name that would otherwise be accessible to the package. A name conflict
involving a shadowing symbol is always resolved in favor of the shadowing
symbol, without signaling an error (except for one instance involving import
described below). The functions shadow and shadowing-import may be used to
declare shadowing symbols.
Name conflicts are detected when they become possible, that is, when the
package structure is altered. There is no need to check for name conflicts
during every name lookup.
The functions use-package, import, and export check for name conflicts.
use-package makes the external symbols of the package being used accessible to
the using package; each of these symbols is checked for name conflicts with the
symbols already accessible. import adds a single symbol to the internals of a
package, checking for a name conflict with an existing symbol either present in
the package or accessible to it. import signals a name conflict error even if
the conflict is with a shadowing symbol, the rationale being that the user has
given two explicit and inconsistent directives. export makes a single symbol
accessible to all the packages that use the package from which the symbol is
exported. All of these packages are checked for name conflicts: (export s p)
does (find-symbol (symbol-name s) q) for each package q in
(package-used-by-list p). Note that in the usual case of an export during the
initial definition of a package, the result of package-used-by-list will be nil
and the name-conflict checking will take negligible time.
The function intern, which is the one used most frequently by the Lisp reader
for looking up names of symbols, does not need to do any name-conflict
checking, because it never creates a new symbol if there is already an
accessible symbol with the name given.
shadow and shadowing-import never signal a name-conflict error because the
user, by calling these functions, has specified how any possible conflict is to
be resolved. shadow does name-conflict checking to the extent that it checks
whether a distinct existing symbol with the specified name is accessible and,
if so, whether it is directly present in the package or inherited. In the
latter case, a new symbol is created to shadow it. shadowing-import does
name-conflict checking to the extent that it checks whether a distinct existing
symbol with the same name is accessible; if so, it is shadowed by the new
symbol, which implies that it must be uninterned if it was directly present in
the package.
unuse-package, unexport, and unintern (when the symbol being uninterned is not
a shadowing symbol) do not need to do any name-conflict checking because they
only remove symbols from a package; they do not make any new symbols
accessible.
Giving a shadowing symbol to unintern can uncover a name conflict that had
previously been resolved by the shadowing. If package A uses packages B and C,
A contains a shadowing symbol x, and B and C each contain external symbols
named x, then removing the shadowing symbol x from A will reveal a name
conflict between b:x and c:x if those two symbols are distinct. In this case
unintern will signal an error.
Aborting from a name-conflict error leaves the original symbol accessible.
Package functions always signal name-conflict errors before making any change
to the package structure. When multiple changes are to be made, however, for
example when export is given a list of symbols, it is permissible for the
implementation to process each change separately, so that aborting from a name
conflict caused by the second symbol in the list will not unexport the first
symbol in the list. However, aborting from a name-conflict error caused by
export of a single symbol will not leave that symbol accessible to some
packages and inaccessible to others; with respect to each symbol processed,
export behaves as if it were an atomic operation.
Continuing from a name-conflict error should offer the user a chance to resolve
the name conflict in favor of either of the candidates. The package structure
should be altered to reflect the resolution of the name conflict, via
shadowing-import, unintern, or unexport.
A name conflict in use-package between a symbol directly present in the using
package and an external symbol of the used package may be resolved in favor of
the first symbol by making it a shadowing symbol, or in favor of the second
symbol by uninterning the first symbol from the using package. The latter
resolution is dangerous if the symbol to be uninterned is an external symbol of
the using package, since it will cease to be an external symbol.
A name conflict in use-package between two external symbols inherited by the
using package from other packages may be resolved in favor of either symbol by
importing it into the using package and making it a shadowing symbol.
A name conflict in export between the symbol being exported and a symbol
already present in a package that would inherit the newly exported symbol may
be resolved in favor of the exported symbol by uninterning the other one, or in
favor of the already-present symbol by making it a shadowing symbol.
A name conflict in export or unintern due to a package inheriting two distinct
symbols with the same name from two other packages may be resolved in favor of
either symbol by importing it into the using package and making it a shadowing
symbol, just as with use-package.
A name conflict in import between the symbol being imported and a symbol
inherited from some other package may be resolved in favor of the symbol being
imported by making it a shadowing symbol, or in favor of the symbol already
accessible by not doing the import. A name conflict in import with a symbol
already present in the package may be resolved by uninterning that symbol, or
by not doing the import.
Good user-interface style dictates that use-package and export, which can cause
many name conflicts simultaneously, first check for all of the name conflicts
before presenting any of them to the user. The user may then choose to resolve
all of them wholesale or to resolve each of them individually, the latter
requiring a lot of interaction but permitting different conflicts to be
resolved different ways.
Implementations may offer other ways of resolving name conflicts. For instance,
if the symbols that conflict are not being used as objects but only as names
for functions, it may be possible to ``merge'' the two symbols by putting the
function definition onto both symbols. References to either symbol for purposes
of calling a function would be equivalent. A similar merging operation can be
done for variable values and for things stored on the property list. In Lisp
Machine Lisp, for example, one can also forward the value, function, and
property cells so that future changes to either symbol will propagate to the
other one. Some other implementations are able to do this with value cells but
not with property lists. Only the user can know whether this way of resolving a
name conflict is adequate, because it will work only if the use of two non-eq
symbols with the same name will not prevent the correct operation of the
program. The value of offering symbol merging as a way of resolving name
conflicts is that it can avoid the need to throw away the whole Lisp world,
correct the package-definition forms that caused the error, and start over from
scratch.
-------------------------------------------------------------------------------
11.6. Built-in Packages
[old_change_begin]
The following packages, at least, are built into every Common Lisp system.
lisp
The package named lisp contains the primitives of the Common Lisp system.
Its external symbols include all of the user-visible functions and global
variables that are present in the Common Lisp system, such as car, cdr,
and *package*. Almost all other packages will want to use lisp so that
these symbols will be accessible without qualification.
user
The user package is, by default, the current package at the time a Common
Lisp system starts up. This package uses the lisp package.
[old_change_end]
[change_begin]
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the forthcoming
ANSI Common Lisp will use the package name common-lisp instead of lisp and the
package name common-lisp-user instead of user. The purpose is to allow a single
Lisp system to support both ``old'' Common Lisp and ``new'' ANSI Common Lisp
simultaneously despite the fact that in some cases the two languages use the
same names for incompatible purposes. (That's what packages are for!)
common-lisp
The package named common-lisp contains the primitives of the ANSI Common
Lisp system (as opposed to a Common Lisp system based on the 1984
specification). Its external symbols include all of the user-visible
functions and global variables that are present in the ANSI Common Lisp
system, such as car, cdr, and *package*. Note, however, that the home
package of such symbols is not necessarily the common-lisp package (this
makes it easier for symbols such as t and lambda to be shared between the
common-lisp package and another package, possibly one named lisp). Almost
all other packages ought to use common-lisp so that these symbols will be
accessible without qualification. This package has the nickname cl.
common-lisp-user
The common-lisp-user package is, by default, the current package at the
time an ANSI Common Lisp system starts up. This package uses the
common-lisp package and has the nickname cl-user. It may contain other
implementation-dependent symbols and may use other implementation-specific
packages.
[change_end]
keyword
This package contains all of the keywords used by built-in or user-defined
Lisp functions. Printed symbol representations that start with a colon are
interpreted as referring to symbols in this package, which are always
external symbols. All symbols in this package are treated as constants
that evaluate to themselves, so that the user can type :foo instead of
':foo.
[old_change_begin]
system
This package name is reserved to the implementation. Normally this is used
to contain names of implementation-dependent system-interface functions.
This package uses lisp and has the nickname sys.
[old_change_end]
[change_begin]
X3J13 voted in January 1989 (PACKAGE-CLUTTER) to modify the requirements on
the built-in packages so as to limit what may appear in the common-lisp package
and to lift the requirement that every implementation have a package named
system. The details are as follows.
Not only must the common-lisp package in any given implementation contain all
the external symbols prescribed by the standard; the common-lisp package
moreover may not contain any external symbol that is not prescribed by the
standard. However, the common-lisp package may contain additional internal
symbols, depending on the implementation.
An external symbol of the common-lisp package may not have a function, macro,
or special form definition, or a top-level value, or a special proclamation, or
a type definition, unless specifically permitted by the standard. Programmers
may validly rely on this fact; for example, fboundp is guaranteed to be false
for all external symbols of the common-lisp package except those explicitly
specified in the standard to name functions, macros, and special forms.
Similarly, boundp will be false of all such external symbols except those
documented to be variables or constants.
Portable programs may use external symbols in the common-lisp package that are
not documented to be constants or variables as names of local lexical variables
with the presumption that the implementation has not proclaimed such variables
to be special; this legitimizes the common practice of using such names as list
and string as names for local variables.
A valid implementation may initially have properties on any symbol, or
dynamically put new properties on symbols (even user-created symbols), as long
as no property indicator used for this purpose is an external symbol of any
package defined by the standard or a symbol that is accessible from the
common-lisp-user package or any package defined by the user.
This vote eliminates the requirement that every implementation have a
predefined package named system. An implementation may provide any number of
predefined packages; these should be described in the documentation for that
implementation.
The common-lisp-user package may contain symbols not described by the standard
and may use other implementation-specific packages.
X3J13 voted in March 1989 (LISP-SYMBOL-REDEFINITION) to restrict user
programs from performing certain actions that might interfere with built-in
facilities or interact badly with them. Except where explicitly allowed, the
consequences are undefined if any of the following actions are performed on a
symbol in the common-lisp package.
* binding or altering its value (lexically or dynamically)
* defining or binding it as a function
* defining or binding it as a macro
* defining it as a type specifier (defstruct, defclass, deftype)
* defining it as a structure (defstruct)
* defining it as a declaration
* dsing it as a symbol macro
* altering its print name
* altering its package
* tracing it
* declaring or proclaiming it special or lexical
* declaring or proclaiming its type or ftype
* removing it from the package common-lisp
X3J13 also voted in June 1989 (DEFINE-COMPILER-MACRO) to add to this list the
item
* defining it as a compiler macro
If such a symbol is not globally defined as a variable or a constant, a user
program is allowed to lexically bind it and declare the type of that binding.
If such a symbol is not defined as a function, macro, or special form, a user
program is allowed to (lexically) bind it as a function and to declare the
ftype of that binding and to trace that binding.
If such a symbol is not defined as a function, macro, or special form, a user
program is allowed to (lexically) bind it as a macro.
As an example, the behavior of the code fragment
(flet ((open (filename &key direction)
(format t "~%OPEN was called.")
(open filename :direction direction)))
(with-open-file (x "frob" :direction ':output)
(format t "~%Was OPEN called?")))
is undefined. Even in a ``reasonable'' implementation, for example, the macro
expansion of with-open-file might refer to the open function and might not.
However, the preceding rules eliminate the burden of deciding whether an
implementation is reasonable. The code fragment violates the rules; officially
its behavior is therefore completely undefined, and that's that.
Note that ``altering the property list'' is not in the list of proscribed
actions, so a user program is permitted to add properties to or remove
properties from symbols in the common-lisp package.
[change_end]
-------------------------------------------------------------------------------
11.7. Package System Functions and Variables
Some of the functions and variables in this section are described in previous
sections but are included here for completeness.
[old_change_begin]
It is up to each implementation's compiler to ensure that when a compiled file
is loaded, all of the symbols in the file end up in the same packages that they
would occupy if the Lisp source file were loaded. In most compilers, this will
be accomplished by treating certain package operations as though they are
surrounded by (eval-when (compile load eval) ...); see eval-when. These
operations are make-package, in-package, shadow, shadowing-import, export,
unexport, use-package, unuse-package, and import. To guarantee proper
compilation in all Common Lisp implementations, these functions should appear
only at top level within a file. As a matter of style, it is suggested that
each file contain only one package, and that all of the package setup forms
appear near the start of the file. This is discussed in more detail, with
examples, in section 11.9.
[old_change_end]
[change_begin]
X3J13 voted in March 1989 (IN-PACKAGE-FUNCTIONALITY) to cancel the
specifications of the preceding paragraph in order to support a model of file
compilation in which the compiler need never take special note of ordinary
function calls; only special forms and macros are recognized as affecting the
state of the compilation process. As part of this change in-package was changed
to be a macro rather than a function and its functionality was restricted. The
actions of shadow, shadowing-import, use-package, import, intern, and export
for compilation purposes may be accomplished with the new macro defpackage.
[change_end]
-------------------------------------------------------------------------------
Implementation note: In the past, some Lisp compilers have read the entire file
into Lisp before processing any of the forms. Other compilers have arranged for
the loader to do all of its intern operations before evaluating any of the
top-level forms. Neither of these techniques will work in a straightforward way
in Common Lisp because of the presence of multiple packages.
-------------------------------------------------------------------------------
For the functions described here, all optional arguments named package default
to the current value of *package*. Where a function takes an argument that is
either a symbol or a list of symbols, an argument of nil is treated as an empty
list of symbols. Any argument described as a package name may be either a
string or a symbol. If a symbol is supplied, its print name will be used as the
package name; if a string is supplied, the user must take care to specify the
same capitalization used in the package name, normally all uppercase.
[Variable]
*package*
The value of this variable must be a package; this package is said to be the
current package. The initial value of *package* is the user package.
[change_begin]
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the forthcoming
ANSI Common Lisp will use the package name common-lisp-user instead of user.
[change_end]
The function load rebinds *package* to its current value. If some form in the
file changes the value of *package* during loading, the old value will be
restored when the loading is completed.
[change_begin]
X3J13 voted in October 1988 (COMPILE-FILE-PACKAGE) to require compile-file to
rebind *package* to its current value.
[change_end]
[Function]
make-package package-name &key :nicknames :use
This creates and returns a new package with the specified package name. As
described above, this argument may be either a string or a symbol. The
:nicknames argument must be a list of strings to be used as alternative names
for the package. Once again, the user may supply symbols in place of the
strings, in which case the print names of the symbols are used. These names and
nicknames must not conflict with any existing package names; if they do, a
correctable error is signaled.
The :use argument is a list of packages or the names (strings or symbols) of
packages whose external symbols are to be inherited by the new package. These
packages must already exist. If not supplied, :use defaults to a list of one
package, the lisp package.
[change_begin]
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the forthcoming
ANSI Common Lisp will use the package name common-lisp instead of lisp.
X3J13 voted in January 1989 (MAKE-PACKAGE-USE-DEFAULT) to change the
specification of make-package so that the default value for the :use argument
is unspecified. Portable code should specify :use '("COMMON-LISP") explicitly.
-------------------------------------------------------------------------------
Rationale: Many existing implementations of Common Lisp happen to have violated
the first edition specification, providing as the default not only the lisp
package but also (or instead) a package containing implementation-dependent
language extensions. This is for good reason: usually it is much more
convenient to the user for the default :use list to be the entire,
implementation-dependent, extended language rather than only the facilities
specified in this book. The X3J13 vote simply legitimizes existing practice.
-------------------------------------------------------------------------------
[change_end]
[old_change_begin]
[Function]
in-package package-name &key :nicknames :use
The in-package function is intended to be placed at the start of a file
containing a subsystem that is to be loaded into some package other than user.
If there is not already a package named package-name, this function is similar
to make-package, except that after the new package is created, *package* is set
to it. This binding will remain in force until changed by the user (perhaps
with another in-package call) or until the *package* variable reverts to its
old value at the completion of a load operation.
If there is an existing package whose name is package-name, the assumption is
that the user is re-loading a file after making some changes. The existing
package is augmented to reflect any new nicknames or new packages in the :use
list (with the usual error checking), and *package* is then set to this
package.
[old_change_end]
[change_begin]
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify that
in-package returns the new package, that is, the value of *package* after the
operation has been executed.
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the forthcoming
ANSI Common Lisp will use the package name common-lisp-user instead of user.
X3J13 voted in March 1989 (IN-PACKAGE-FUNCTIONALITY) to restrict the
functionality of in-package and to make it a macro. This is an incompatible
change.
Making in-package a macro rather than a function means that there is no need to
require compile-file to handle it specially. Since defpackage is also defined
to have side effects on the compilation environment, there is no need to
require any of the package functions to be treated specially by the compiler.
[Macro]
in-package name
This macro causes *package* to be set to the package named name, which must be
a symbol or string. The name is not evaluated. An error is signaled if the
package does not already exist. Everything this macro does is also performed at
compile time if the call appears at top level.
[change_end]
[Function]
find-package name
The name must be a string that is the name or nickname for a package. This
argument may also be a symbol, in which case the symbol's print name is used.
The package with that name or nickname is returned; if no such package exists,
find-package returns nil. The matching of names observes case (as in string=).
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
find-package to accept a package object, in which case the package is simply
returned (see section 11.2).
[change_end]
[Function]
package-name package
The argument must be a package. This function returns the string that names
that package.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
package-name to accept a package name or nickname, in which case the primary
name of the package so specified is returned (see section 11.2).
X3J13 voted in January 1989 (PACKAGE-DELETION) to add a function to delete
packages. One consequence of this vote is that package-name will return nil
instead of a package name if applied to a deleted package object. See
delete-package.
[change_end]
[Function]
package-nicknames package
The argument must be a package. This function returns the list of nickname
strings for that package, not including the primary name.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
package-nicknames to accept a package name or nickname, in which case the
nicknames of the package so specified are returned (see section 11.2).
[change_end]
[Function]
rename-package package new-name &optional new-nicknames
The old name and all of the old nicknames of package are eliminated and are
replaced by new-name and new-nicknames. The new-name argument is a string or
symbol; the new-nicknames argument, which defaults to nil, is a list of strings
or symbols.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify that
rename-package returns package.
[change_end]
[Function]
package-use-list package
A list of other packages used by the argument package is returned.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
package-used-by-list package
A list of other packages that use the argument package is returned.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
package-shadowing-symbols package
A list is returned of symbols that have been declared as shadowing symbols in
this package by shadow or shadowing-import. All symbols on this list are
present in the specified package.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
list-all-packages
This function returns a list of all packages that currently exist in the Lisp
system.
[change_begin]
[Function]
delete-package package
X3J13 voted in January 1989 (PACKAGE-DELETION) to add the delete-package
function, which deletes the specified package from all package system data
structures. The package argument may be either a package or the name of a
package.
If package is a name but there is currently no package of that name, a
correctable error is signaled. Continuing from the error makes no deletion
attempt but merely returns nil from the call to delete-package.
If package is a package object that has already been deleted, no error is
signaled and no deletion is attempted; instead, delete-package immediately
returns nil.
If the package specified for deletion is currently used by other packages, a
correctable error is signaled. Continuing from this error, the effect of the
function unuse-package is performed on all such other packages so as to remove
their dependency on the specified package, after which delete-package proceeds
to delete the specified package as if no other package had been using it.
If any symbol had the specified package as its home package before the call to
delete-package, then its home package is unspecified (that is, the contents of
its package cell are unspecified) after the delete-package operation has been
completed. Symbols in the deleted package are not modified in any other way.
The name and nicknames of the package cease to be recognized package names. The
package object is still a package, but anonymous; packagep will be true of it,
but package-name applied to it will return nil.
The effect of any other package operation on a deleted package object is
undefined. In particular, an attempt to locate a symbol within a deleted
package (using intern or find-symbol, for example) will have unspecified
results.
delete-package returns t if the deletion succeeds, and nil otherwise.
[change_end]
[Function]
intern string &optional package
The package, which defaults to the current package, is searched for a symbol
with the name specified by the string argument. This search will include
inherited symbols, as described in section 11.4. If a symbol with the specified
name is found, it is returned. If no such symbol is found, one is created and
is installed in the specified package as an internal symbol (as an external
symbol if the package is the keyword package); the specified package becomes
the home package of the created symbol.
[change_begin]
X3J13 voted in March 1989 (CHARACTER-PROPOSAL) to specify that intern may in
effect perform the search using a copy of the argument string in which some or
all of the implementation-defined attributes have been removed from the
characters of the string. It is implementation-dependent which attributes are
removed.
[change_end]
Two values are returned. The first is the symbol that was found or created. The
second value is nil if no pre-existing symbol was found, and takes on one of
three values if a symbol was found:
:internal
The symbol was directly present in the package as an internal symbol.
:external
The symbol was directly present as an external symbol.
:inherited
The symbol was inherited via use-package (which implies that the symbol is
internal).
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
-------------------------------------------------------------------------------
Compatibility note: Conceptually, intern translates a string to a symbol. In
MacLisp and several other dialects of Lisp, intern can take either a string or
a symbol as its argument; in the latter case, the symbol's print name is
extracted and used as the string. However, this leads to some confusing issues
about what to do if intern finds a symbol that is not eq to the argument
symbol. To avoid such confusion, Common Lisp requires the argument to be a
string.
-------------------------------------------------------------------------------
[Function]
find-symbol string &optional package
This is identical to intern, but it never creates a new symbol. If a symbol
with the specified name is found in the specified package, directly or by
inheritance, the symbol found is returned as the first value and the second
value is as specified for intern. If the symbol is not accessible in the
specified package, both values are nil.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
unintern symbol &optional package
If the specified symbol is present in the specified package, it is removed from
that package and also from the package's shadowing-symbols list if it is
present there. Moreover, if the package is the home package for the symbol, the
symbol is made to have no home package. Note that in some circumstances the
symbol may continue to be accessible in the specified package by inheritance.
unintern returns t if it actually removed a symbol, and nil otherwise.
unintern should be used with caution. It changes the state of the package
system in such a way that the consistency rules do not hold across the change.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
-------------------------------------------------------------------------------
Compatibility note: The equivalent of this in MacLisp is remob.
-------------------------------------------------------------------------------
[Function]
export symbols &optional package
The symbols argument should be a list of symbols, or possibly a single symbol.
These symbols become accessible as external symbols in package (see section
11.4). export returns t.
By convention, a call to export listing all exported symbols is placed near the
start of a file to advertise which of the symbols mentioned in the file are
intended to be used by other programs.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
unexport symbols &optional package
The argument should be a list of symbols, or possibly a single symbol. These
symbols become internal symbols in package. It is an error to unexport a symbol
from the keyword package (see section 11.4). unexport returns t.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
import symbols &optional package
The argument should be a list of symbols, or possibly a single symbol. These
symbols become internal symbols in package and can therefore be referred to
without having to use qualified-name (colon) syntax. import signals a
correctable error if any of the imported symbols has the same name as some
distinct symbol already accessible in the package (see section 11.4). import
returns t.
[change_begin]
X3J13 voted in June 1987 (IMPORT-SETF-SYMBOL-PACKAGE) to clarify that if any
symbol to be imported has no home package then import sets the home package of
the symbol to the package to which the symbol is being imported.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
shadowing-import symbols &optional package
This is like import, but it does not signal an error even if the importation of
a symbol would shadow some symbol already accessible in the package. In
addition to being imported, the symbol is placed on the shadowing-symbols list
of package (see section 11.5). shadowing-import returns t.
shadowing-import should be used with caution. It changes the state of the
package system in such a way that the consistency rules do not hold across the
change.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
shadow symbols &optional package
The argument should be a list of symbols, or possibly a single symbol. The
print name of each symbol is extracted, and the specified package is searched
for a symbol of that name. If such a symbol is present in this package
(directly, not by inheritance), then nothing is done. Otherwise, a new symbol
is created with this print name, and it is inserted in the package as an
internal symbol. The symbol is also placed on the shadowing-symbols list of the
package (see section 11.5). shadow returns t.
[change_begin]
X3J13 voted in March 1988 (SHADOW-ALREADY-PRESENT) to change shadow to accept
strings as well as well as symbols (a string in the symbols list being treated
as a print name), and to clarify that if a symbol of specified name is already
in the package but is not yet on the shadowing-symbols list for that package,
then shadow does add it to the shadowing-symbols list rather than simply doing
nothing.
[change_end]
shadow should be used with caution. It changes the state of the package system
in such a way that the consistency rules do not hold across the change.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
use-package packages-to-use &optional package
The packages-to-use argument should be a list of packages or package names, or
possibly a single package or package name. These packages are added to the
use-list of package if they are not there already. All external symbols in the
packages to use become accessible in package as internal symbols (see section
11.4). It is an error to try to use the keyword package. use-package returns t.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
[change_end]
[Function]
unuse-package packages-to-unuse &optional package
The packages-to-unuse argument should be a list of packages or package names,
or possibly a single package or package name. These packages are removed from
the use-list of package. unuse-package returns t.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
X3J13 voted in January 1989 (DEFPACKAGE) to add a macro defpackage to the
language to make it easier to create new packages, alleviating the burden on
the programmer to perform the various setup operations in exactly the correct
sequence.
[Macro]
defpackage defined-package-name {option}*
This creates a new package, or modifies an existing one, whose name is
defined-package-name. The defined-package-name may be a string or a symbol; if
it is a symbol, only its print name matters, and not what package, if any, the
symbol happens to be in. The newly created or modified package is returned as
the value of the defpackage form.
Each standard option is a list of a keyword (the name of the option) and
associated arguments. No part of a defpackage form is evaluated. Except for the
:size option, more than one option of the same kind may occur within the same
defpackage form.
The standard options for defpackage are as follows. In every case, any option
argument called package-name or symbol-name may be a string or a symbol; if it
is a symbol, only its print name matters, and not what package, if any, the
symbol happens to be in.
(:size integer)
This specifies approximately the number of symbols expected to be in the
package. This is purely an efficiency hint to the storage allocator, so
that implementations using hash tables as part of the package data
structure (the usual technique) will not have to incrementally expand the
package as new symbols are added to it (for example, as a large file is
read while ``in'' that package).
(:nicknames {package-name}*)
The specified names become nicknames of the package being defined. If any
of the specified nicknames already refers to an existing package, a
continuable error is signaled exactly as for the function make-package.
(:shadow {symbol-name}*)
Symbols with the specified names are created as shadows in the package
being defined, just as with the function shadow.
(:shadowing-import-from package-name {symbol-name}*)
Symbols with the specified names are located in the specified package.
These symbols are imported into the package being defined, shadowing other
symbols if necessary, just as with the function shadowing-import. In no
case will symbols be created in a package other than the one being
defined; a continuable error is signaled if for any symbol-name there is
no symbol of that name accessible in the package named package-name.
(:use {package-name}*)
The package being defined is made to ``use'' (inherit from) the packages
specified by this option, just as with the function use-package. If no
:use option is supplied, then a default list is assumed as for
make-package.
X3J13 voted in January 1989 (MAKE-PACKAGE-USE-DEFAULT) to change the
specification of make-package so that the default value for the :use
argument is unspecified. This change affects defpackage as well. Portable
code should specify (:use '("COMMON-LISP")) explicitly.
(:import-from package-name {symbol-name}*)
Symbols with the specified names are located in the specified package.
These symbols are imported into the package being defined, just as with
the function import. In no case will symbols be created in a package other
than the one being defined; a continuable error is signaled if for any
symbol-name there is no symbol of that name accessible in the package
named package-name.
(:intern {symbol-name}*)
Symbols with the specified names are located or created in the package
being defined, just as with the function intern. Note that the action of
this option may be affected by a :use option, because an inherited symbol
will be used in preference to creating a new one.
(:export {symbol-name}*)
Symbols with the specified names are located or created in the package
being defined and then exported, just as with the function export. Note
that the action of this option may be affected by a :use, :import-from, or
:shadowing-import-from option, because an inherited or imported symbol
will be used in preference to creating a new one.
The order in which options appear in a defpackage form does not matter; part of
the convenience of defpackage is that it sorts out the options into the correct
order for processing. Options are processed in the following order:
1. :shadow and :shadowing-import-from
2. :use
3. :import-from and :intern
4. :export
Shadows are established first in order to avoid spurious name conflicts when
use links are established. Use links must occur before importing and interning
so that those operations may refer to normally inherited symbols rather than
creating new ones. Exports are performed last so that symbols created by any of
the other options, in particular, shadows and imported symbols, may be
exported. Note that exporting an inherited symbol implicitly imports it first
(see section 11.4).
If no package named defined-package-name already exists, defpackage creates it.
If such a package does already exist, then no new package is created. The
existing package is modified, if possible, to reflect the new definition. The
results are undefined if the new definition is not consistent with the current
state of the package.
An error is signaled if more than one :size option appears.
An error is signaled if the same symbol-name argument (in the sense of
comparing names with string=) appears more than once among the arguments to all
the :shadow, :shadowing-import-from, :import-from, and :intern options.
An error is signaled if the same symbol-name argument (in the sense of
comparing names with string=) appears more than once among the arguments to all
the :intern and :export options.
Other kinds of name conflicts are handled in the same manner that the
underlying operations use-package, import, and export would handle them.
Implementations may support other defpackage options. Every implementation
should signal an error on encountering a defpackage option it does not support.
The function compile-file should treat top-level defpackage forms in the same
way it would treat top-level calls to package-affecting functions (as described
at the beginning of section 11.7).
Here is an example of a call to defpackage that ``plays it safe'' by using only
strings as names.
(cl:defpackage "MY-VERY-OWN-PACKAGE"
(:size 496)
(:nicknames "MY-PKG" "MYPKG" "MVOP")
(:use "COMMON-LISP")
(:shadow "CAR" "CDR")
(:shadowing-import-from "BRAND-X-LISP" "CONS")
(:import-from "BRAND-X-LISP" "GC" "BLINK-FRONT-PANEL-LIGHTS")
(:export "EQ" "CONS" "MY-VERY-OWN-FUNCTION"))
The preceding defpackage example is designed to operate correctly even if the
package current when the form is read happens not to ``use'' the common-lisp
package. (Note the use in this example of the nickname cl for the common-lisp
package.) Moreover, neither reading in nor evaluating this defpackage form will
ever create any symbols in the current package. Note too the use of uppercase
letters in the strings.
Here, for the sake of contrast, is a rather similar use of defpackage that
``plays the whale'' by using all sorts of permissible syntax.
(defpackage my-very-own-package
(:export :EQ common-lisp:cons my-very-own-function)
(:nicknames "MY-PKG" #:MyPkg)
(:use "COMMON-LISP")
(:shadow "CAR")
(:size 496)
(:nicknames mvop)
(:import-from "BRAND-X-LISP" "GC" Blink-Front-Panel-Lights)
(:shadow common-lisp::cdr)
(:shadowing-import-from "BRAND-X-LISP" CONS))
This example has exactly the same effect on the newly created package but may
create useless symbols in other packages. The use of explicit package tags is
particularly confusing; for example, this defpackage form will cause the symbol
cdr to be shadowed in the new package; it will not be shadowed in the package
common-lisp. The fact that the name ``CDR'' was specified by a
package-qualified reference to a symbol in the common-lisp package is a red
herring. The moral is that the syntactic flexibility of defpackage, as in other
parts of Common Lisp, yields considerable convenience when used with
commonsense competence, but unutterable confusion when used with Malthusian
profusion.
-------------------------------------------------------------------------------
Implementation note: An implementation of defpackage might choose to transform
all the package-name and symbol-name arguments into strings at macro expansion
time, rather than at the time the resulting expansion is executed, so that even
if source code is expressed in terms of strange symbols in the defpackage form,
the binary file resulting from compiling the source code would contain only
strings. The purpose of this is simply to minimize the creation of useless
symbols in production code. This technique is permitted as an implementation
strategy but is not a behavior required by the specification of defpackage.
-------------------------------------------------------------------------------
Note that defpackage is not capable by itself of defining mutually recursive
packages, for example two packages each of which uses the other. However,
nothing prevents one from using defpackage to perform much of the initial setup
and then using functions such as use-package, import, and export to complete
the links.
The purpose of defpackage is to encourage the user to put the entire definition
of a package and its relationships to other packages in a single place. It may
also encourage the designer of a large system to place the definitions of all
relevant packages into a single file (say) that can be loaded before loading or
compiling any code that depends on those packages. Such a file, if carefully
constructed, can simply be loaded into the common-lisp-user package.
Implementations and programming environments may also be better able to support
the programming process (if only by providing better error checking) through
global knowledge of the intended package setup.
[change_end]
[Function]
find-all-symbols string-or-symbol
find-all-symbols searches every package in the Lisp system to find every symbol
whose print name is the specified string. A list of all such symbols found is
returned. This search is case-sensitive. If the argument is a symbol, its print
name supplies the string to be searched for.
[Macro]
do-symbols (var [package [result-form]])
{declaration}* {tag | statement}*
do-symbols provides straightforward iteration over the symbols of a package.
The body is performed once for each symbol accessible in the package, in no
particular order, with the variable var bound to the symbol. Then result-form
(a single form, not an implicit progn) is evaluated, and the result is the
value of the do-symbols form. (When the result-form is evaluated, the control
variable var is still bound and has the value nil.) If the result-form is
omitted, the result is nil. return may be used to terminate the iteration
prematurely. If execution of the body affects which symbols are contained in
the package, other than possibly to remove the symbol currently the value of
var by using unintern, the effects are unpredictable.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
X3J13 voted in March 1988 (DO-SYMBOLS-DUPLICATES) to specify that the body of
a do-symbols form may be executed more than once for the same accessible
symbol, and users should take care to allow for this possibility.
The point is that the same symbol might be accessible via more than one chain
of inheritance, and it is implementationally costly to eliminate such
duplicates. Here is an example:
(setq *a* (make-package 'a)) ;Implicitly uses package common-lisp
(setq *b* (make-package 'b)) ;Implicitly uses package common-lisp
(setq *c* (make-package 'c :use '(a b)))
(do-symbols (x *c*) (print x)) ;Symbols in package common-lisp
; might be printed once or twice here
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict
user side effects; see section 7.9.
Note that the loop construct provides a kind of for clause that can iterate
over the symbols of a package (see chapter 26).
[change_end]
[Macro]
do-external-symbols (var [package [result]])
{declaration}* {tag | statement}*
do-external-symbols is just like do-symbols, except that only the external
symbols of the specified package are scanned. The clarification voted by X3J13
in March 1988 for do-symbols (DO-SYMBOLS-DUPLICATES) , regarding redundant
executions of the body for the same symbol, applies also to
do-external-symbols.
[change_begin]
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict
user side effects; see section 7.9.
[change_end]
[Macro]
do-all-symbols (var [result-form])
{declaration}* {tag | statement}*
This is similar to do-symbols but executes the body once for every symbol
contained in every package. (This will not process every symbol whatsoever,
because a symbol not accessible in any package will not be processed. Normally,
uninterned symbols are not accessible in any package.) It is not in general the
case that each symbol is processed only once, because a symbol may appear in
many packages.
[change_begin]
The clarification voted by X3J13 in March 1988 for do-symbols
(DO-SYMBOLS-DUPLICATES) , regarding redundant executions of the body for the
same symbol, applies also to do-all-symbols.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that
the package argument may be either a package object or a package name (see
section 11.2).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict
user side effects; see section 7.9.
X3J13 voted in January 1989 (HASH-TABLE-PACKAGE-GENERATORS) to add a new
macro with-package-iterator to the language.
[Macro]
with-package-iterator (mname package-list {symbol-type}+)
{form}*
The name mname is bound and defined as if by macrolet, with the body forms as
its lexical scope, to be a ``generator macro'' such that each invocation of
(mname) will return a symbol and that successive invocations will eventually
deliver, one by one, all the symbols from the packages that are elements of the
list that is the value of the expression package-list (which is evaluated
exactly once).
Each element of the package-list value may be either a package or the name of a
package. As a further convenience, if the package-list value is itself a
package or the name of a package, it is treated as if a singleton list
containing that value had been provided. If the package-list value is nil, it
is considered to be an empty list of packages.
At each invocation of the generator macro, there are two possibilities. If
there is yet another unprocessed symbol, then four values are returned: t, the
symbol, a keyword indicating the accessibility of the symbol within the package
(see below), and the package from which the symbol was accessed. If there are
no more unprocessed symbols in the list of packages, then one value is
returned: nil.
When the generator macro returns a symbol as its second value, the fourth value
is always one of the packages present or named in the package-list value, and
the third value is a keyword indicating accessibility: :internal means present
in the package and not exported; :external means present and exported; and
:inherited means not present (thus not shadowed) but inherited from some
package used by the package that is the fourth value.
Each symbol-type in an invocation of with-package-iterator is not evaluated.
More than one may be present; their order does not matter. They indicate the
accessibility types of interest. A symbol is not returned by the generator
macro unless its actual accessibility matches one of the symbol-type
indicators. The standard symbol-type indicators are :internal, :external, and
:inherited, but implementations are permitted to extend the syntax of
with-package-iterator by recognizing additional symbol accessibility types. An
error is signaled if no symbol-type is supplied, or if any supplied symbol-type
is not recognized by the implementation.
The order in which symbols are produced by successive invocations of the
generator macro is not necessarily correlated in any way with the order of the
packages in the package-list. When more than one package is in the
package-list, symbols accessible from more than one package may be produced
once or more than once. Even when only one package is specified, symbols
inherited in multiple ways via used packages may be produced once or more than
once.
The implicit interior state of the iteration over the list of packages and the
symbols within them has dynamic extent. It is an error to invoke the generator
macro once the with-package-iterator form has been exited.
Any number of invocations of with-package-iterator and related macros may be
nested, and the generator macro of an outer invocation may be called from
within an inner invocation (provided, of course, that its name is visible or
otherwise made available).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict
user side effects; see section 7.9.
-------------------------------------------------------------------------------
Rationale: This facility is a bit more flexible in some ways than do-symbols
and friends. In particular, it makes it possible to implement loop clauses for
iterating over packages in a way that is both portable and efficient (see
chapter 26).
-------------------------------------------------------------------------------
[change_end]
-------------------------------------------------------------------------------
11.8. Modules
A module is a Common Lisp subsystem that is loaded from one or more files. A
module is normally loaded as a single unit, regardless of how many files are
involved. A module may consist of one package or several packages. The
file-loading process is necessarily implementation-dependent, but Common Lisp
provides some very simple portable machinery for naming modules, for keeping
track of which modules have been loaded, and for loading modules as a unit.
[change_begin]
X3J13 voted in January 1989 (REQUIRE-PATHNAME-DEFAULTS) to eliminate the
entire module facility from the language; that is, the variable *modules* and
the functions provide and require are deleted. X3J13 commented that the
file-loading feature of require is not portable, and that the remaining
functionality is easily implemented by user code. (I will add that in any case
the specification of require is so vague that different implementations are
likely to have differing behavior.)
[change_end]
[Variable]
*modules*
The variable *modules* is a list of names of the modules that have been loaded
into the Lisp system so far. This list is used by the functions provide and
require.
[Function]
provide module-name
require module-name &optional pathname
Each module has a unique name (a string). The provide and require functions
accept either a string or a symbol as the module-name argument. If a symbol is
provided, its print name is used as the module name. If the module consists of
a single package, it is customary for the package and module names to be the
same.
The provide function adds a new module name to the list of modules maintained
in the variable *modules*, thereby indicating that the module in question has
been loaded.
The require function tests whether a module is already present (using a
case-sensitive comparison); if the module is not present, require proceeds to
load the appropriate file or set of files. The pathname argument, if present,
is a single pathname or a list of pathnames whose files are to be loaded in
order, left to right. If the pathname argument is nil or is not provided, the
system will attempt to determine, in some system-dependent manner, which files
to load. This will typically involve some central registry of module names and
the associated file lists.
[change_begin]
X3J13 voted in March 1988 not to permit symbols as pathnames (PATHNAME-SYMBOL)
and to specify exactly which streams may be used as pathnames
(PATHNAME-STREAM) (see section 23.1.6). Of course, this is moot if require is
not in the language.
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify that the
values returned by provide and require are implementation-dependent. Of course,
this is moot if provide and require are not in the language.
[change_end]
-------------------------------------------------------------------------------
Implementation note: One way to implement such a registry on many operating
systems is simply to use a distinguished ``library'' directory within the file
system, where the name of each file is the same as the module it contains.
-------------------------------------------------------------------------------
11.9. An Example
[old_change_begin]
Most users will want to load and use packages but will never need to build one.
Often a user will load a number of packages into the user package whenever
using Common Lisp. Typically an implementation might provide some sort of
initialization file mechanism to make such setup automatic when the Lisp starts
up. Table 11-1 shows such an initialization file, one that simply causes other
facilities to be loaded.
[old_change_end]
[change_begin]
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the forthcoming
ANSI Common Lisp will use the package name common-lisp-user instead of user.
[change_end]
----------------------------------------------------------------
Table 11-1: An Initialization File
;;;; Lisp init file for I. Newton.
;;; Set up the USER package the way I like it.
(require 'calculus) ;I use CALCULUS a lot; load it.
(use-package 'calculus) ;Get easy access to its
; exported symbols.
(require 'newtonian-mechanics) ;Same thing for NEWTONIAN-MECHANICS
(use-package 'newtonian-mechanics)
;;; I just want a few things from RELATIVITY,
;;; and other things conflict.
;;; Import only what I need into the USER package.
(require 'relativity)
(import '(relativity:speed-of-light
relativity:ignore-small-errors))
;;; These are worth loading, but I will use qualified names,
;;; such as PHLOGISTON:MAKE-FIRE-BOTTLE, to get at any symbols
;;; I might need from these packages.
(require 'phlogiston)
(require 'alchemy)
;;; End of Lisp init file for I. Newton.
----------------------------------------------------------------
When each of two files uses some symbols from the other, the author of those
files must be careful to arrange the contents of the file in the proper order.
Typically each file contains a single package that is a complete module. The
contents of such a file should include the following items, in order:
1. A call to provide that announces the module name.
2. A call to in-package that establishes the package.
3. A call to shadow that establishes any local symbols that will shadow
symbols that would otherwise be inherited from packages that this package
will use.
4. A call to export that establishes all of this package's external symbols.
5. Any number of calls to require to load other modules that the contents of
this file might want to use or refer to. (Because the calls to require
follow the calls to in-package, shadow, and export, it is possible for the
packages that may be loaded to refer to external symbols in this package.)
6. Any number of calls to use-package, to make external symbols from other
packages accessible in this package.
7. Any number of calls to import, to make symbols from other packages
present in this package.
8. Finally, the definitions making up the contents of this package/module.
The following mnemonic sentence may be helpful in remembering the proper order
of these calls:
Put in seven extremely random user interface commands.
Each word of the sentence corresponds to one item in the above ordering:
Put Provide
IN IN-package
Seven Shadow
EXtremely EXport
Random Require
USEr USE-package
Interface Import
COmmands COntents of package/module
The sentence says what it helps you to do.
[change_begin]
The most distressing aspect of the X3J13 vote to eliminate provide and require
(REQUIRE-PATHNAME-DEFAULTS) is of course that it completely ruins the
mnemonic sentence.
[change_end]
Now, suppose for the sake of example that the phlogiston and alchemy packages
are single-file, single-package modules as described above. The phlogiston
package needs to use the alchemy package, and the alchemy package needs to use
several external symbols from the phlogiston package. The definitions in the
alchemy and phlogiston files (see tables 11-2 and 11-3) allow a user to specify
require statements for either of these modules, or for both of them in either
order, and all relevant information will be loaded automatically and in the
correct order.
----------------------------------------------------------------
Table 11-2: File alchemy
;;;; Alchemy functions, written and maintained by Merlin, Inc.
(provide 'alchemy) ;The module is named ALCHEMY.
(in-package 'alchemy) ;So is the package.
;;; There is nothing to shadow.
;;; Here is the external interface.
(export '(lead-to-gold gold-to-lead
antimony-to-zinc elixir-of-life))
;;; This package/module needs a function from
;;; the PHLOGISTON package/module.
(require 'phlogiston)
;;; We don't frequently need most of the external symbols from
;;; PHLOGISTON, so it's not worth doing a USE-PACKAGE on it.
;;; We'll just use qualified names as needed. But we use
;;; one function, MAKE-FIRE-BOTTLE, a lot, so import it.
;;; It's external in PHLOGISTON and so can be referred to
;;; here using ":" qualified-name syntax.
(import '(phlogiston:make-fire-bottle))
;;; Now for the real contents of this file.
(defun lead-to-gold (x)
"Takes a quantity of lead and returns gold."
(when (> (phlogiston:heat-flow 5 x x) ;Using a qualified symbol
3)
(make-fire-bottle x)) ;Using an imported symbol
(gild x))
;;; And so on ...
----------------------------------------------------------------
----------------------------------------------------------------
Table 11-3: File phlogiston
;;;; Phlogiston functions, by Thermofluidics, Ltd.
(provide 'phlogiston) ;The module is named PHLOGISTON.
(in-package 'phlogiston) ;So is the package.
;;; There is nothing to shadow.
;;; Here is the external interface.
(export '(heat-flow cold-flow mix-fluids separate-fluids
burn make-fire-bottle))
;;; This file uses functions from the ALCHEMY package/module.
(require 'alchemy)
;;; We use alchemy functions a lot, so use the package.
;;; This will allow symbols exported from the ALCHEMY package
;;; to be referred to here without the need for qualified names.
(use-package 'alchemy)
;;; No calls to IMPORT are needed here.
;;; The real contents of this package/module.
(defvar *feeling-weak* nil)
(defun heat-flow (amount x y)
"Make some amount of heat flow from x to y."
(when *feeling-weak*
(quaff (elixir-of-life))) ;No qualifier is needed.
(push-heat amount x y))
;;; And so on ...
----------------------------------------------------------------
[old_change_begin]
For very large modules whose contents are spread over several files (the lisp
package is an example), it is recommended that the user create the package and
declare all of the shadows and external symbols in a separate file, so that
this can be loaded before anything that might use symbols from this package.
[old_change_end]
[change_begin]
Indeed, the defpackage macro approved by X3J13 in January 1989 (DEFPACKAGE)
encourages the use of such a separate file. (By the way, X3J13 voted in March
1989 (LISP-PACKAGE-NAME) to specify that the forthcoming ANSI Common Lisp
will use the package name common-lisp instead of lisp.) Let's take a look at a
revision of I. Newton's files using defpackage.
The new version of the initialization file avoids using require; instead, we
assume that load will do the job (see table 11-4).
----------------------------------------------------------------
Table 11-4: An Initialization File When defpackage Is Used
;;;; Lisp init file for I. Newton.
;;; Set up the USER package the way I like it.
(load "calculus") ;I use CALCULUS a lot; load it.
(use-package 'calculus) ;Get easy access to its
; exported symbols.
(load "newtonian-mechanics") ;Ditto for NEWTONIAN-MECHANICS
(use-package 'newtonian-mechanics)
;;; I just want a few things from RELATIVITY,
;;; and other things conflict.
;;; Import only what I need into the USER package.
(load "relativity")
(import '(relativity:speed-of-light
relativity:ignore-small-errors))
;;; These are worth loading, but I will use qualified names,
;;; such as PHLOGISTON:MAKE-FIRE-BOTTLE, to get at any symbols
;;; I might need from these packages.
(load "phlogiston")
(load "alchemy")
;;; End of Lisp init file for I. Newton.
----------------------------------------------------------------
The other files have each been split into two parts, one that establishes the
package and one that defines the contents. This example uses a simple
convention that for any file named, say, ``foo'' the file named ``foo-package''
contains the necessary defpackage and/or other package-establishing code. The
idiom
(unless (find-package "FOO")
(load "foo-package"))
is conventionally used to load a package definition but only if the package has
not already been defined. (This is a bit clumsy, and there are other ways to
arrange things so that a package is defined no more than once.)
The file alchemy-package is shown in table 11-5. The tricky point here is that
the alchemy and phlogiston packages contain mutual references (each imports
from the other), and so defpackage alone cannot do the job. Therefore the
phlogiston package is not mentioned in a :use option in the defpackage for the
alchemy package. Instead, the function use-package is called explicitly, after
the package definition for phlogiston has been loaded. Note that this file has
been coded with excruciating care so as to operate correctly even if the
package current when the file is loaded does not inherit from the common-lisp
package. In particular, the standard load-package-definition idiom has been
peppered with package qualifiers:
(cl:unless (cl:find-package "PHLOGISTON")
(cl:load "phlogiston-package"))
Note the use of the nickname cl for the common-lisp package.
The alchemy file, shown in table 11-6, simply loads the alchemy package
definition, makes that package current, and then defines the ``real contents''
of the package.
----------------------------------------------------------------
Table 11-5: File alchemy-package Using defpackage
;;;; Alchemy package, written and maintained by Merlin, Inc.
(cl:defpackage "ALCHEMY"
(:export "LEAD-TO-GOLD" "GOLD-TO-LEAD"
"ANTIMONY-TO-ZINC" "ELIXIR-OF-LIFE")
)
;;; This package needs a function from the PHLOGISTON package.
;;; Load the definition of the PHLOGISTON package if necessary.
(cl:unless (cl:find-package "PHLOGISTON")
(cl:load "phlogiston-package"))
;;; We don't frequently need most of the external symbols from
;;; PHLOGISTON, so it's not worth doing a USE-PACKAGE on it.
;;; We'll just use qualified names as needed. But we use
;;; one function, MAKE-FIRE-BOTTLE, a lot, so import it.
;;; It's external in PHLOGISTON and so can be referred to
;;; here using ":" qualified-name syntax.
(cl:import '(phlogiston:make-fire-bottle))
----------------------------------------------------------------
----------------------------------------------------------------
Table 11-6: File alchemy Using defpackage
;;;; Alchemy functions, written and maintained by Merlin, Inc.
(unless (find-package "ALCHEMY")
(load "alchemy-package"))
(in-package 'alchemy)
(defun lead-to-gold (x)
"Takes a quantity of lead and returns gold."
(when (> (phlogiston:heat-flow 5 x x) ;Using a qualified symbol
3)
(make-fire-bottle x)) ;Using an imported symbol
(gild x))
;;; And so on ...
----------------------------------------------------------------
The file phlogiston-package is shown in table 11-7. This one is a little more
straightforward than the file alchemy-package, because the latter bears the
responsibility for breaking the circular package references. This file simply
makes sure that the alchemy package is defined and then performs a defpackage
for the phlogiston package.
----------------------------------------------------------------
Table 11-7: File phlogiston-package Using defpackage
;;;; Phlogiston package definition, by Thermofluidics, Ltd.
;;; This package uses functions from the ALCHEMY package.
(cl:unless (cl:find-package "ALCHEMY")
(cl:load "alchemy-package"))
(cl:defpackage "PHLOGISTON"
(:use "COMMON-LISP" "ALCHEMY")
(:export "HEAT-FLOW"
"COLD-FLOW"
"MIX-FLUIDS"
"SEPARATE-FLUIDS"
"BURN"
"MAKE-FIRE-BOTTLE")
)
----------------------------------------------------------------
The phlogiston file, shown in table 11-8, simply loads the phlogiston package
definition, makes that package current, and then defines the ``real contents''
of the package.
----------------------------------------------------------------
Table 11-8: File phlogiston Using defpackage
;;;; Phlogiston functions, by Thermofluidics, Ltd.
(unless (find-package "PHLOGISTON")
(load "phlogiston-package"))
(in-package 'phlogiston)
(defvar *feeling-weak* nil)
(defun heat-flow (amount x y)
"Make some amount of heat flow from x to y."
(when *feeling-weak*
(quaff (elixir-of-life))) ;No qualifier is needed.
(push-heat amount x y))
;;; And so on ...
----------------------------------------------------------------
Let's look at the question of package circularity in this example a little more
closely. Suppose that the file alchemy-package is loaded first. It defines the
alchemy package and then loads file phlogiston-package. That file in turn finds
that the package alchemy has already been defined and therefore does not
attempt to load file alchemy-package again; it merely defines package
phlogiston. The file alchemy-package then has a chance to import
phlogiston:make-fire-bottle and everything is fine.
On the other hand, suppose that the file phlogiston-package is loaded first. It
finds that the package alchemy has not already been defined, and therefore it
immediately loads file alchemy-package. That file in turn defines the alchemy
package; then it finds that package phlogiston is not yet defined and so loads
file phlogiston-package again (indeed, in nested fashion). This time file
phlogiston-package does find that the package alchemy has already been defined,
so it simply defines package phlogiston and terminates. The file
alchemy-package then imports phlogiston:make-fire-bottle and terminates.
Finally, the outer loading of file phlogiston-package re-defines package
phlogiston. Oh, dear. Fortunately the two definitions of package phlogiston
agree in every detail, so everything ought to be all right. Still, it looks a
bit dicey; I certainly don't have the same warm, fuzzy feeling that I would if
no package were defined more than once.
Conclusion: defpackage goes a long way, but it certainly doesn't solve all the
possible problems of package and file management. Neither did require and
provide. Perhaps further experimentation will yield facilities appropriate for
future standardization.
[change_end]
-------------------------------------------------------------------------------